﻿// Copyright © Microsoft Corporation.  All Rights Reserved.
// This code released under the terms of the 
// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Xml.Linq;

namespace TheOliver.Controls
{
    public class TwitterReader : UserControl, INotifyPropertyChanged
    {

        public TwitterReader()
        {
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                StackPanel sp = new StackPanel();
                sp.Background = new SolidColorBrush(Colors.Red);

                TextBlock tb = new TextBlock();
                tb.Text = "[Twitter Reader Service]";

                sp.Children.Add(tb);
                this.Content = sp;
                return;
            }

            this.Loaded += (s, e) =>
                {
                    Load(this.TwitterUser);
                };
        }

        public string TwitterUser
        {
            get { return (string)GetValue(TwitterUserProperty); }
            set { SetValue(TwitterUserProperty, value); }
        }

        public static readonly DependencyProperty TwitterUserProperty =
            DependencyProperty.Register(
                "TwitterUser", 
                typeof(string),
                typeof(TwitterReader), 
                new PropertyMetadata(string.Empty, OnTwitterUserChanged));

        public static void OnTwitterUserChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            TwitterReader tr = sender as TwitterReader;
            if (DesignerProperties.GetIsInDesignMode(tr))
            {
                return;
            }
            tr.Load(args.NewValue as string);
        }

        private bool _isBusy = false;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                _isBusy = value;
                OnPropertyChanged("IsBusy");
                this.IsIdle = !_isBusy;
            }
        }

        private bool _isIdle = true;
        public bool IsIdle
        {
            get { return _isIdle; }
            set
            {
                _isIdle = value;
                OnPropertyChanged("IsIdle");
            }
        }

        public bool AutoLoad
        {
            get { return (bool)GetValue(AutoLoadProperty); }
            set { SetValue(AutoLoadProperty, value); }
        }

        public static readonly DependencyProperty AutoLoadProperty =
            DependencyProperty.Register(
                "AutoLoad", 
                typeof(bool), 
                typeof(TwitterReader), 
                new PropertyMetadata(true));

        public IEnumerable<TwitterItem> TwitterItems
        {
            get { return (IEnumerable<TwitterItem>)GetValue(TwitterItemsProperty); }
            set { SetValue(TwitterItemsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TwitterItems.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TwitterItemsProperty =
            DependencyProperty.Register(
            "TwitterItems", 
            typeof(IEnumerable<TwitterItem>), 
            typeof(TwitterReader), 
            new PropertyMetadata(null, OnTwitterItemsChanged));

        private static void OnTwitterItemsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {

        }

        public void Load()
        {
            if (TwitterUser == null || TwitterUser.Length <= 0)
            {
                RaiseError(new Exception("No Twitter User defined"));
                return;
            }

            this.IsBusy = true;

            string twitterLink = "http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=" + this.TwitterUser;
            Uri twitterUri = new Uri(twitterLink);

            WebClient twitter = new WebClient();
            twitter.DownloadStringCompleted += new DownloadStringCompletedEventHandler(twitter_DownloadStringCompleted);
            twitter.DownloadStringAsync(twitterUri);
        }

        void  twitter_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                RaiseError(e.Error);
                return;
            }

            XElement xmlTweets = XElement.Parse(e.Result);
            IEnumerable<TwitterItem> twitterItems = from tweet in xmlTweets.Descendants("status")
                                                    select new TwitterItem
                                                    {
                                                        ImageSource = tweet.Element("user").Element("profile_image_url").Value,
                                                        Message = tweet.Element("text").Value,
                                                        Username = tweet.Element("user").Element("screen_name").Value
                                                    };
            OnFeedLoaded(twitterItems.ToArray());
        }

        public void Load(string twitterUser)
        {
            this.TwitterUser = twitterUser;
            Load();
        }

        public event FeedLoadedEventHandler FeedLoaded;
        public event FeedErrorEventHandler FeedError;

        private void OnFeedLoaded(TwitterItem[] twitterItems)
        {
            this.IsBusy = false;
            if (FeedLoaded != null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    FeedLoadedEventArgs args = new FeedLoadedEventArgs();
                    args.TwitterItems = twitterItems;
                    FeedLoaded(this, args);
                });
            }
            this.TwitterItems = twitterItems;
        }

        private void RaiseError(Exception exc)
        {
            this.IsBusy = false;
            if (FeedError != null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    FeedErrorEventArgs args = new FeedErrorEventArgs();
                    args.Error = exc;
                    FeedError(this, args);
                });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                });
            }
        }

    }

    public delegate void FeedLoadedEventHandler(object sender, FeedLoadedEventArgs args);

    public class FeedLoadedEventArgs : EventArgs
    {

        public  TwitterItem[] TwitterItems { get; set; }
    }

    public delegate void FeedErrorEventHandler(object sender, FeedErrorEventArgs args);

    public class FeedErrorEventArgs
    {
        public Exception Error { get; set; }
    }

    public class TwitterItem
    {
        public string Username { get; set; }
        public string Message { get; set; }
        public string ImageSource { get; set; }
    }

}
